package com.srwl.mytx.domain;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.OSSRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.srwl.mytx.BuildConfig;
import com.srwl.mytx.Helper;
import com.srwl.mytx.utils.FileUtils;
import com.srwl.mytx.utils.TextUtil;

import java.io.File;
import java.io.InputStream;

public class AliOssService {
    private static final AliOssService ourInstance = new AliOssService();
    private OSSClient oss;
    private static final String USER_AVATAR_BUCKET = "u-a";
    private static final String TOPIC_IMAGE_BUCKET = "t-i";
    private static final String TOPIC_VIDEO_BUCKET = "t-v";
    private static final String IM_IMAGE_BUCKET = "im-i";
    private static final String IM_AUDIO_BUCKET = "im-a";
    private static final String IM_VIDEO_BUCKET = "im-v";
    private static String endpoint = "http://oss-cn-beijing.aliyuncs.com";
    public static String USER_AVATAR_PRE_URL = "http://u-a.oss-cn-beijing.aliyuncs.com/";
    public static String TOPIC_IMAGE_PRE_URL = "http://topici.mytx.tech/";//"http://t-i.oss-cn-beijing.aliyuncs.com/";//使用加速
    public static String TOPIC_VIDEO_PRE_URL = "http://topicv.mytx.tech/";//"http://t-v.oss-cn-beijing.aliyuncs.com/";

    public static AliOssService getInstance() {
        return ourInstance;
    }

    private AliOssService() {
    }


    public void initAliOSS(Context context) {
        String stsServer = BuildConfig.STS_SERVER_URL;
        // 推荐使用OSSAuthCredentialsProvider。token过期可以及时更新。
        OSSCredentialProvider credentialProvider = new OSSAuthCredentialsProvider(stsServer);
        // 配置类如果不设置，会有默认配置。
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒。
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒。
        conf.setMaxConcurrentRequest(5); // 最大并发请求数，默认5个。
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次。

        oss = new OSSClient(context, endpoint, credentialProvider);
    }

    public void downloadAudio(String audioName, OssListener loadListener) {
        downLoadObject(audioName, IM_AUDIO_BUCKET, loadListener, "", "");
    }

    public void downloadVideo(String videoName, OssListener loadListener) {
        downLoadObject(videoName, IM_VIDEO_BUCKET, loadListener, "", "");
    }

    public void downloadImage(String imageName, OssListener loadListener) {
        downLoadObject(imageName, IM_IMAGE_BUCKET, loadListener, "", "");
    }

    /**
     * @param filePreviewName 本地保存的时候文件名前缀
     * @param imageName
     * @param style           阿里云oss 图片处理策略
     * @param loadListener
     */
    public void downloadImage(String filePreviewName, String imageName, String style, OssListener loadListener) {
        downLoadObject(imageName, IM_IMAGE_BUCKET, loadListener, style, filePreviewName);
    }



     /*
     主题视频和图片设置公开读，视频用饺子播放器加载，图片用 Glide 加载，以后有必要，可以拿到oss-sdk的源码， 把关键鉴权部分copy 下来，整合进 饺子播放器 加载数据里面，
      */

    public void downLoadObject(String objectKey, String bucket, OssListener loadListener, String style, String fileNamePreview) {
        final long get_start = System.currentTimeMillis();
        if ((objectKey == null) || objectKey.equals("")) {
            Log.w("AsyncGetImage", "ObjectNull");
            return;
        }

        OSSLog.logDebug("create GetObjectRequest");
        GetObjectRequest get = new GetObjectRequest(bucket, objectKey + style);
        get.setCRC64(OSSRequest.CRC64Config.YES);
        get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                Log.d("GetObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                int progress = (int) (100 * currentSize / totalSize);
                if (loadListener != null) {
                    loadListener.onProgressChange(progress);
                }

            }
        });
        OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                // 请求成功
                InputStream inputStream = result.getObjectContent();
                // Bitmap bitmap = ImageUtils.getBitmap(inputStream);
                String filePath = Helper.getInstance().getFilePath();
                FileUtils.writeFile(filePath, fileNamePreview + objectKey, inputStream);
                if (loadListener != null) {
                    loadListener.onSuccess(objectKey);
                }

            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientException, ServiceException serviceException) {

                // 请求异常
                if (clientException != null) {
                    // 本地异常如网络异常等
                    clientException.printStackTrace();
                    if (loadListener != null) {
                        loadListener.onFailure("本地异常", clientException.toString());
                    }
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.toString());
                    if (loadListener != null) {
                        loadListener.onFailure(serviceException.getErrorCode(), serviceException.toString());
                    }
                }

            }
        });

    }

    public void uploadImImage(String imageName, String localFile, OssListener listener) {
        uploadObject(imageName, IM_IMAGE_BUCKET, localFile, listener);
    }

    public void uploadImAudio(String audioName, String localFile, OssListener listener) {
        uploadObject(audioName, IM_AUDIO_BUCKET, localFile, listener);
    }

    public void uploadImVideo(String videoName, String localFile, OssListener listener) {
        uploadObject(videoName, IM_VIDEO_BUCKET, localFile, listener);
    }

    public void uploadTopicImage(String imageName, String localFile, OssListener listener) {
        uploadObject(imageName, TOPIC_IMAGE_BUCKET, localFile, listener);
    }

    public void uploadUserAvatar(String imageName, String localFile, OssListener listener) {
        uploadObject(imageName, USER_AVATAR_BUCKET, localFile, listener);
    }

    public void uploadTopicVideo(String videoName, String localFile, OssListener listener) {
        uploadObject(videoName, TOPIC_VIDEO_BUCKET, localFile, listener);
    }

    public void uploadObject(String objectKey, String bucket, String localFile, OssListener listener) {
        final long upload_start = System.currentTimeMillis();
        OSSLog.logDebug("upload start");

        if (objectKey.equals("") || TextUtils.isEmpty(localFile)) {
            Log.w("AsyncPutImage", "ObjectNull");
            if (listener != null) {
                listener.onFailure("", "文件key为空或者文件地址为空");
            }
            return;
        }

        File file = new File(localFile);
        if (!file.exists()) {
            Log.w("AsyncPutImage", "FileNotExist");
            Log.w("LocalFile", localFile);
            if (listener != null) {
                listener.onFailure("文件不存在", localFile);
            }
            return;
        }

        // 构造上传请求
        OSSLog.logDebug("create PutObjectRequest ");
        PutObjectRequest put = new PutObjectRequest(bucket, objectKey, localFile);
        put.setCRC64(OSSRequest.CRC64Config.YES);


        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                int progress = (int) (100 * currentSize / totalSize);
                if (listener != null) {
                    listener.onProgressChange(progress);
                }
            }
        });

        OSSLog.logDebug(" asyncPutObject ");
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");

                Log.d("ETag", result.getETag());
                Log.d("RequestId", result.getRequestId());

                long upload_end = System.currentTimeMillis();
                OSSLog.logDebug("upload cost: " + (upload_end - upload_start) / 1000f);
                if (listener != null) {
                    listener.onSuccess(objectKey);
                }

            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    info = clientExcepion.toString();
                    if (listener != null) {
                        listener.onFailure("本地异常", info);
                    }
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    info = serviceException.toString();
                    if (listener != null) {
                        listener.onFailure(serviceException.getErrorCode(), info);
                    }
                }

            }
        });
    }


    public interface OssListener {

        void onProgressChange(int progress);

        /**
         * @param objectKey 文件名字，加上bucket 和 endpoint 就是路径
         */
        void onSuccess(String objectKey);

        void onFailure(String errorCode, String message);

    }

}
